package com.myzl.coal.service.impl;

import cn.hutool.core.date.DateTime;
import com.myzl.coal.mongo.component.MongoComponent;
import com.myzl.coal.mongo.domain.HistoryData;
import com.myzl.coal.service.MongoHistoryDataMapper;
import com.myzl.common.enums.DeviceCommandEnum;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.ConvertOperators;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.schema.JsonSchemaObject;
import org.springframework.stereotype.Service;

import java.util.List;

import static org.springframework.data.mongodb.core.aggregation.Aggregation.newAggregation;

/**
 * @ClassName: HistoryDataImpl
 * @Author: wzb
 * @Date: 2023/6/12 10:00
 * @Description:
 */
@Slf4j(topic = "admin-user")
@Service
@Data
public class MongoHistoryDataMapperImpl implements MongoHistoryDataMapper {

    private final MongoComponent mongoComponent;

    @Override
    public List<HistoryData> selectList(Integer deviceId, List<Integer> params, DateTime createTime) {
        Criteria criteria = new Criteria();
        criteria.andOperator(
                Criteria.where("deviceId").is(deviceId),
                Criteria.where("dictValue").in(params),
                Criteria.where("createTime").gte(createTime)
        );
        List<HistoryData> dataList = mongoComponent.selectList(criteria, HistoryData.class);
        return dataList;
    }

    @Override
    public HistoryData selectOne(Integer deviceId, Integer dictValue) {
        Criteria criteria = new Criteria();
        criteria.andOperator(
                Criteria.where("deviceId").is(deviceId),
                Criteria.where("dictValue").is(dictValue)
        );
        Sort startSort = Sort.by(Sort.Order.asc("createTime"));
        return mongoComponent.findOne(criteria, startSort, HistoryData.class);
    }

    @Override
    public HistoryData selectOneDesc(Integer deviceId, Integer dictValue) {
        Criteria criteria = new Criteria();
        criteria.andOperator(
                Criteria.where("deviceId").is(deviceId),
                Criteria.where("dictValue").is(dictValue)
        );
        Sort startSort = Sort.by(Sort.Order.desc("createTime"));
        return mongoComponent.findOne(criteria, startSort, HistoryData.class);
    }

    @Override
    public String selectMax(Integer deviceId, Integer dictValue) {
        final Aggregation aggregation = newAggregation(
                Aggregation.match(Criteria.where("deviceId").is(deviceId)),
                Aggregation.match(Criteria.where("dictValue").is(dictValue)),
                Aggregation.group("dictValue").max(ConvertOperators.Convert.convertValueOf("dataValue").to(JsonSchemaObject.Type.doubleType())).as("dataValueMax"),
                Aggregation.limit(1)
        );
        return mongoComponent.findMax(aggregation, HistoryData.class);
    }

    @Override
    public HistoryData selectOne(Integer deviceId, Integer dictValue, DateTime createTime) {
        Criteria criteria = new Criteria();
        criteria.andOperator(
                Criteria.where("deviceId").is(deviceId),
                Criteria.where("dictValue").is(dictValue),
                Criteria.where("createTime").gte(createTime)
        );
        Sort startSort = Sort.by(Sort.Order.asc("createTime"));
        return mongoComponent.findOne(criteria, startSort, HistoryData.class);
    }

    @Override
    public boolean deleteList(Integer deviceId, List<String> idList, DateTime createTime) {
        Criteria criteria = new Criteria();
        criteria.andOperator(
                Criteria.where("deviceId").is(deviceId),
                Criteria.where("_id").nin(idList),
                Criteria.where("dictValue").ne(DeviceCommandEnum.CURRENT_DENSITY.getCode()),
                Criteria.where("createTime").lt(createTime)
        );
        Sort startSort = Sort.by(Sort.Order.asc("createTime"));
        return mongoComponent.remove(criteria, startSort, HistoryData.class) > 0;
    }

    @Override
    public boolean deleteList(Integer deviceType, DateTime createTime) {
        Criteria criteria = new Criteria();
        criteria.andOperator(
                Criteria.where("deviceType").ne(deviceType),
                Criteria.where("createTime").lt(createTime)
        );
        Sort startSort = Sort.by(Sort.Order.asc("createTime"));
        return mongoComponent.remove(criteria, startSort, HistoryData.class) > 0;
    }
}
